# 编译器设置
CXX := g++
CXXFLAGS := -Wall -Wextra -std=c++17 -g
INCLUDES := -IscNet/include
LDFLAGS := -lpthread

# 目录设置
SRC_DIR := scNet/src
EXAMPLE_DIR := scNet/example
TEST_DIR := scNet/test
OBJ_DIR := obj
BIN_DIR := bin

# 确保输出目录存在
$(shell mkdir -p $(OBJ_DIR) $(BIN_DIR))

# 文件列表
SRCS := $(wildcard $(SRC_DIR)/*.cpp)
EXAMPLE_SRCS := $(wildcard $(EXAMPLE_DIR)/*.cpp)
TEST_SRCS := $(wildcard $(TEST_DIR)/*.cpp)

# 对象文件生成规则
OBJS := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRCS))
EXAMPLE_OBJS := $(patsubst $(EXAMPLE_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(EXAMPLE_SRCS))
TEST_OBJS := $(patsubst $(TEST_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(TEST_SRCS))

# 可执行文件列表
EXECUTABLES := $(BIN_DIR)/server_example $(BIN_DIR)/client_example
TEST_EXECUTABLES := $(BIN_DIR)/test_server $(BIN_DIR)/test_client

.PHONY: all clean test

all: $(EXECUTABLES)

test: $(TEST_EXECUTABLES)

# 编译规则 - 使用完整路径模式匹配
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
	$(CXX) $(CXXFLAGS) $(INCLUDES) -MMD -c $< -o $@

$(OBJ_DIR)/%.o: $(EXAMPLE_DIR)/%.cpp
	$(CXX) $(CXXFLAGS) $(INCLUDES) -MMD -c $< -o $@

$(OBJ_DIR)/%.o: $(TEST_DIR)/%.cpp
	$(CXX) $(CXXFLAGS) $(INCLUDES) -MMD -c $< -o $@

# 链接规则
$(BIN_DIR)/server_example: $(OBJ_DIR)/server_example.o $(OBJS)
	$(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS)

$(BIN_DIR)/client_example: $(OBJ_DIR)/client_example.o $(OBJS)
	$(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS)

$(BIN_DIR)/test_server: $(OBJ_DIR)/test_server.o $(OBJS)
	$(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS)

$(BIN_DIR)/test_client: $(OBJ_DIR)/test_client.o $(OBJS)
	$(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS)

clean:
	rm -rf $(OBJ_DIR) $(BIN_DIR)

# 自动依赖处理
-include $(wildcard $(OBJ_DIR)/*.d)